#include "cache.hpp"
#include <pthread.h>
#include <errno.h>

extern int xx;

void* copykeyX(void*);
void freekeyX(void*);
void freevalue(void*);




struct Value{
	char x[100];
};


/* search required for the btree */
int bsearchX(void* b1, void* b2){
	//printf("Search %s %s %d\n", (char*)b1, (char*)b2, strcmp((char*)b1,(char*)b2));
	return strcmp((char*)b1,(char*)b2);
}
void showlist(void* n){
	if(((fsnode*)n)->status!=FSSTATUS_DELETED){
		//printf("node %s\n", (char*)((fsnode*)n)->key);
	}
	else{
		//printf("node -\n");
	}
}
void showtree(void* k, void* v){
	printf("Key: %s   Value:%s\n", (char*)k, (char*) (   ((Value*)(  ((fsnode*)v)->payload   ))->x   )           ) ;
}





void* copykeyX(void* k){
	return strdup((char*)k);
}
void freekeyX(void* k){
	free(k);
}
void freevalueX(void* v){
	free(v);
}

















char* intx[]={"sakkaliya", "vaddha", "hakaralla", "pissa", "valballa", "xmam", "ninja", "crab", "zebra", "vtec", "turbo", "rambo", "pakaya", "owns", "zulu","gansy"};
int intxs = 16;

void* tfunc(void* x){
	fsstore * fs =(fsstore*)x;

	Value * v ;
	char* c;
	int j;
	int ret;
	int r, y;
	for(y =0 ; y < 1000; y++){
		r=rand() % 16 ;
		switch(10){
			case 1:
			case 2:
			case 6:
				break;
				printf("about to add %s\n", intx[r]);
				v = (Value*)malloc(sizeof(Value));
				c = strdup(intx[r]);
				sprintf(v->x, "%s-sex", c);
				if(!(ret=fs->fsadd(c, v))){
					printf("addded %s\n", c);
				}
				else{
					printf("exists %s %d\n", c, ret);
					free(c);
					free(v);
				}
				break;
			case 3:
				break;
				printf("about to delete %s\n", intx[r]);
				fs->fsdelete((char*)intx[r]);
				printf("deleted %s\n", intx[r]);
				break;
			case 4:
				break;
				printf("about to lock oldest %s\n", intx[r]);
				v = (Value*)fs->fslockoldest((void**)&c);
				if(v){
					printf("lockedold %s\n", v->x);
					usleep(r*500);
					printf("about to unlock %s\n", c);
					fs->fsunlock(c);
				}
				else
					printf("not there old\n");

				break;
			case 5:
				//fs->fsprunedellist();
				break;
			default:
				c=intx[r];
				//printf("%d %d about to lock %s\n", y, pthread_self(), intx[r]);
				v = (Value*)fs->fslock(c);
				if(v){
					printf("locked %s %s\n", c, v->x);
					usleep(r*500);
					//printf("about to unlock %s\n", c);
					fs->fsunlock(c);
					//printf("unlocked %s \n", c);
				}
				else{
					//printf("not there %s\n", c);
				}

				break;
		}
	}
	//printf("tread finished\n");
	//fs->fsshow(showtree, showlist);
	printf("------%d\n", y);
	return 0;
}



int main(int cc, char** vv){

	int numberofthreads=10;


	fsstore* fs = new fsstore(20, bsearchX, freekeyX, freevalueX, copykeyX);

	Value * v;
	v= (Value*)malloc(sizeof(Value));
	char* c = strdup("turbo");
	sprintf(v->x, "%s-sex", c);
	fs->fsadd(c, v);

	v= (Value*)malloc(sizeof(Value));
	c = strdup("pervert");
	sprintf(v->x, "%s-sex", c);
	fs->fsadd(c, v);

	fs->fsshow(showtree, showlist);

	printf("------------OK--------\n");


       	pthread_t threadid[100];

	for(int i = 0 ; i < numberofthreads; i++ ){
       		assert(0==pthread_create(&(threadid[i]), 0, tfunc, fs));
	}

	for(int i = 0 ; i < numberofthreads; i++ ){
		printf( "--------joining %d\n", threadid[i]);
		assert(0==pthread_join((threadid[i]), 0));
	}

	//fs.fsshow(showtree, showlist);

	//fs.fsshow(showtree, showlist);
}
